//============================================================================================
/**
 * @file	scr_pokethlon.c
 * @brief	スクリプトコマンド：ポケスロン関連
 * @author	Nozomu Saito
 * @date	08.07.24
 */
//============================================================================================
#include "common.h"
#include "system/lib_pack.h"
#include "fieldsys.h"

#include "script.h"
#include "scrcmd_def.h"
#include "field/eventflag.h"
#include "field/evwkdef.h"
#include "sysflag.h"
#include "syswork.h"

///#include "savedata/perapvoice.h"
#include "field/field_hblank.h"
#include "field/fieldmap_work.h"
#include "savedata/zukanwork.h"
#include "field/zonedata.h"

#include "system/pmfprint.h"
#include "communication/comm_tool.h"

typedef struct{
///	CONTEST_GAME_PARAM c_game;		///<コンテスト：ゲーム進行パラメータ
	POKEPARTY *poke_party;			///<手持ちポケモンの構造体
///	void *perap_voice[BREEDER_MAX];	///<ぺラップの鳴き声データへのポインタ
///	void *class_proc;				///<現在の部門の管理ワークへのポインタ
///	u8 class_flag;					///<現在実行中の部門(CON_CLASS_???)
	u8 sio_flag;					///<TRUE：通信中
///	u8 actin_sort[BREEDER_MAX];		///<演技力部門開始時の並び順

///	u8 seq;
///	int work;
///	int wait;
///	TCB_PTR sio_tcb;

	//通信の送受信バッファ
///	u8 recieve_buf[CC_NETID_MAX][CC_RECIEVE_BUF_MAX];	///<受信バッファ
///	u8 recieve_count;				///<受信データを受け取った人数をカウント
///	u8 huge_buf[CON_HUGEBUF_SIZE];				///<巨大データ送信用バッファ
///	u8 recieve_huge_buf[CC_NETID_MAX][CON_HUGEBUF_SIZE];		///<巨大データ受信用バッファ

	//コンフィグ
///	const CONFIG *config;		///<コンフィグデータへのポインタ
	//セーブデータ
	SAVEDATA *sv;				///<セーブデータへのポインタ
	POKEMON_PARAM *my_pp;		///<出場させる自分の手持ちポケモンへのポインタ(フィールド上の)
								///<最後にリボンなどをセットさせる為に持っています。
	const MYSTATUS *my_status;	///<マイステータスへのポインタ
///	u8 temoti_pos;				///<出場させるポケモンの手持ち位置
///	u8 hof_flag;				///<殿堂入りフラグ
///	u8 zenkoku_zukan_flag;		///<全国図鑑フラグ

	//イメージクリップ画面用(コンテスト内部では使用しません)
///	IMC_SAVEDATA *imc_save;		///<イメージクリップのセーブデータへのポインタ
///	CON_IMC_LOCAL imc_local;	///<イメージクリップ内で使用するワーク
///	void *icpw;					///<イメージクリップ画面構成用初期化データへのポインタ

	//スクリプト上で使用するワーク
///	CONSCR_CAMERA_FLASH *conscr_flash;		///<カメラのフラッシュ制御ワーク

	//ランダムの種退避用ワーク
///	u32 push_random_seed;		///<イベント進行時のランダムの種退避用ワーク
}POKETHLON_SYSTEM;

//--------------------------------------------------------------
/**
 * @brief   ポケスロンシステム作成初期データ
 */
//--------------------------------------------------------------
typedef struct{
	u8 type;							///<CONTYPE_???
	u8 rank;							///<CONRANK_???
	u8 mode;							///<CONMODE_???
	u8 hof_flag;						///<殿堂入りフラグ(TRUE:殿堂入りしている)
	u8 zenkoku_zukan_flag;				///<全国図鑑入手フラグ(TRUE:入手している)
	u8 temoti_pos;				///<出場させるポケモンの手持ち位置
	POKEMON_PARAM *my_pp;				///<出場させる自分の手持ちポケモンへのポインタ
	const STRBUF *player_name_str;		///<プレイヤー名へのポインタ
	const MYSTATUS *my_status;			///<マイステータスへのポインタ
///	IMC_SAVEDATA *imc_save;				///<イメージクリップセーブデータワークへのポインタ
	const CONFIG *config;				///<コンフィグへのポインタ
	SAVEDATA *sv;						///<セーブデータへのポインタ
///	void *perap_voice;					///<ぺラップボイスへのポインタ
}PKTH_INIT_DATA;

//============================================================================================
//
//	プロトタイプ宣言
//
//============================================================================================
static BOOL EvWaitPkthSioTimingCheck(VM_MACHINE * core);
BOOL EvCmdPkthSioTimingSend( VM_MACHINE * core );
BOOL EvCmdPkthSioTimingCheck( VM_MACHINE * core );
BOOL EvCmdPkthSystemCreate( VM_MACHINE * core );
BOOL EvCmdPkthSystemExit( VM_MACHINE * core );
BOOL EvCmdPkthMyEntryNoGet( VM_MACHINE * core );
BOOL EvCmdPkthMsgPrintFlagSet( VM_MACHINE * core );

void PkthScr_SioTimingSend(POKETHLON_SYSTEM *pkthsys, u8 timing_no);
BOOL PkthScr_SioTimingCheck(POKETHLON_SYSTEM *pkthsys, u8 timing_no);

POKETHLON_SYSTEM * Pokethlon_SystemCreate(const PKTH_INIT_DATA *pid);
void Pokethlon_SystemExit(POKETHLON_SYSTEM *pkthsys);

//============================================================================================
//
//	コマンド
//
//============================================================================================

//--------------------------------------------------------------------------------------------
/**
 * 送信
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdPkthSioTimingSend( VM_MACHINE * core )
{
	void** pwork	= GetEvScriptWorkMemberAdrs( core->fsys, ID_EVSCR_PWORK );
	u16 timing_no	= VMGetWorkValue(core);

	PkthScr_SioTimingSend( *pwork, timing_no );
	return 0;
}

//--------------------------------------------------------------------------------------------
/**
 * 同期チェック
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"1"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdPkthSioTimingCheck( VM_MACHINE * core )
{
	void** pwork	= GetEvScriptWorkMemberAdrs( core->fsys, ID_EVSCR_PWORK );
	u16 timing_no	= VMGetWorkValue(core);

	//仮想マシンの汎用レジスタにワークのIDを格納
	core->reg[0] = timing_no;

	VM_SetWait( core, EvWaitPkthSioTimingCheck );
	return 1;
}

//--------------------------------------------------------------------------------------------
/**
 * 同期チェック
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"1"＝終了
 */
//--------------------------------------------------------------------------------------------
static BOOL EvWaitPkthSioTimingCheck(VM_MACHINE * core)
{
	void** pwork		= GetEvScriptWorkMemberAdrs( core->fsys, ID_EVSCR_PWORK );
	return PkthScr_SioTimingCheck( *pwork, core->reg[0] );
}

//--------------------------------------------------------------------------------------------
/**
 * システムワーク作成
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdPkthSystemCreate( VM_MACHINE * core )
{
///	STRBUF* buf;
///	POKEMON_PARAM * poke;
	void** pwork	= GetEvScriptWorkMemberAdrs( core->fsys, ID_EVSCR_PWORK );
///	MYSTATUS* my	= SaveData_GetMyStatus( GameSystem_GetSaveData(core->fsys) );
	u16 rank		= VMGetWorkValue(core);
	u16 type		= VMGetWorkValue(core);
	u16 mode		= VMGetWorkValue(core);
	u16 pos			= VMGetWorkValue(core);
	PKTH_INIT_DATA pid;

	//ポケモンへのポインタ取得
///	poke = PokeParty_GetMemberPointer( SaveData_GetTemotiPokemon(core->fsys->savedata), pos );

	//自分の名前取得
///	buf	= MyStatus_CreateNameString( my, HEAPID_FIELD );

	pid.type = type;
	pid.rank = rank;
	pid.mode = mode;
///	pid.hof_flag = SysFlag_GameClearCheck(SaveData_GetEventWork(core->fsys->savedata));
///	pid.zenkoku_zukan_flag =
///		ZukanWork_GetZenkokuZukanFlag(SaveData_GetZukanWork(core->fsys->savedata));
///	pid.temoti_pos = pos;
///	pid.my_pp = poke;
///	pid.player_name_str = buf;
///	pid.my_status = my;
///	pid.imc_save = SaveData_GetImcSaveData(core->fsys->savedata);
///	pid.config = SaveData_GetConfig(core->fsys->savedata);
	pid.sv = core->fsys->savedata;
///	pid.perap_voice = SaveData_GetPerapVoice(core->fsys->savedata);

	*pwork = Pokethlon_SystemCreate(&pid);

	//STRBUF開放
///	STRBUF_Delete( buf );

	return 0;
}

//--------------------------------------------------------------------------------------------
/**
 * システムワーク削除
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdPkthSystemExit( VM_MACHINE * core )
{
	POKEMON_PARAM * poke;
	void** pwork	= GetEvScriptWorkMemberAdrs( core->fsys, ID_EVSCR_PWORK );
	u16 pos			= VMGetWorkValue(core);	//参加したポケモンが手持ちの何番目か取得
	u32 place_id = ZoneData_GetPlaceNameID(core->fsys->location->zone_id);

	Pokethlon_SystemExit( *pwork );
	return 0;
}

//--------------------------------------------------------------------------------------------
/**
 * 自分のエントリー番号を取得
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdPkthMyEntryNoGet( VM_MACHINE * core )
{
	void** pwork		= GetEvScriptWorkMemberAdrs( core->fsys, ID_EVSCR_PWORK );
	u16* ret_wk			= VMGetWork( core );

	*ret_wk = 0;//ConScr_MyEntryNoGet( *pwork );
	return 0;
}

//--------------------------------------------------------------------------------------------
/**
 * ポケスロンのメッセージ送り設定を行う
 *
 * @param	core		仮想マシン制御構造体へのポインタ
 *
 * @return	"0"
 */
//--------------------------------------------------------------------------------------------
BOOL EvCmdPkthMsgPrintFlagSet( VM_MACHINE * core )
{
	void** pwork		= GetEvScriptWorkMemberAdrs( core->fsys, ID_EVSCR_PWORK );

	MsgPrintFlagSet( TRUE );
	return 0;
}

//--------------------------------------------------------------
/**
 * @brief   スクリプト用命令：通信同期待ち命令送信
 *
 * @param   pkthsys			ポケスロンシステムワークへのポインタ
 * @param   timing_no		タイミング番号
 *
 * 非通信の時は何もしません
 */
//--------------------------------------------------------------
void PkthScr_SioTimingSend(POKETHLON_SYSTEM *pkthsys, u8 timing_no)
{
	if(pkthsys->sio_flag == FALSE){
		return;
	}
	CommTimingSyncStart(timing_no);
}

//--------------------------------------------------------------
/**
 * @brief   スクリプト用命令：通信同期、受信待ち
 *
 * @param   pkthsys			ポケスロンシステムワークへのポインタ
 * @param   timing_no		タイミング番号
 *
 * @retval  TRUE:同期取れた。　FALSE:待ち中
 *
 * 非通信の時はTRUEのみが返ります
 */
//--------------------------------------------------------------
BOOL PkthScr_SioTimingCheck(POKETHLON_SYSTEM *pkthsys, u8 timing_no)
{
	if(pkthsys->sio_flag == FALSE){
		return TRUE;
	}

	if(CommIsTimingSync(timing_no) == TRUE){
		return TRUE;
	}
	return FALSE;
}

//--------------------------------------------------------------
/**
 * @brief   ポケスロンシステムワークをAllocする
 *
 * @retval  ポケスロンシステムワークへのポインタ
 */
//--------------------------------------------------------------
static POKETHLON_SYSTEM * Pokethlon_SystemWorkAlloc(void)
{
	POKETHLON_SYSTEM *pkthsys;
	int i;

	pkthsys = sys_AllocMemory(HEAPID_CONTEST, sizeof(POKETHLON_SYSTEM));
	MI_CpuClear8(pkthsys, sizeof(POKETHLON_SYSTEM));
///	pkthsys->c_game.my_breeder_no = 0;
///	pkthsys->c_game.player_num = 1;
///	pkthsys->c_game.cpu_num = BREEDER_MAX - 1;
	return pkthsys;
}

//--------------------------------------------------------------
/**
 * @brief   システムワークを作成する
 *
 * @param   pid
 *
 * @retval  作成したポケスロンシステムワークへのポインタ
 */
//--------------------------------------------------------------
POKETHLON_SYSTEM * Pokethlon_SystemCreate(const PKTH_INIT_DATA *pid)
{
	POKETHLON_SYSTEM *pkthsys;

	sys_CreateHeap(HEAPID_WORLD, HEAPID_CONTEST, (0x3000 + 0x1000));
	pkthsys = Pokethlon_SystemWorkAlloc();

///	pkthsys->push_random_seed = gf_get_seed();
///	contest_srand(pkthsys);

///	pkthsys->c_game.type = cid->type;
///	pkthsys->c_game.rank = cid->rank;
///	pkthsys->c_game.mode = cid->mode;
///	pkthsys->c_game.theme = ConTool_ThemeRandomSelect(cid->rank, FALSE);
///	pkthsys->c_game.server_no = pkthsys->c_game.my_breeder_no;
///	pkthsys->c_game.my_version = CONTEST_VERSION;
///	pkthsys->c_game.server_version = pkthsys->c_game.my_version;
///	pkthsys->c_game.special_judge_no = 1;//contest_rand(pkthsys) % JUDGE_MAX;

///	pkthsys->imc_save = cid->imc_save;
///	pkthsys->config = cid->config;
///	pkthsys->sv = cid->sv;
///	pkthsys->my_pp = cid->my_pp;
///	pkthsys->temoti_pos = cid->temoti_pos;
///	pkthsys->my_status = cid->my_status;
///	pkthsys->hof_flag = cid->hof_flag;
///	pkthsys->zenkoku_zukan_flag = cid->zenkoku_zukan_flag;
	OS_Printf("システム作成\n");
	return pkthsys;
}

//--------------------------------------------------------------
/**
 * @brief   Contest_SystemCreateを使用して作ったポケスロンシステムワークを解放する
 *
 * @param   consys		ポケスロンシステムワークへのポインタ
 */
//--------------------------------------------------------------
void Pokethlon_SystemExit(POKETHLON_SYSTEM *pkthsys)
{
	//ランダムの種復帰
///	gf_srand(consys->push_random_seed);

	//Contest_SystemWorkFree(consys);
	sys_FreeMemoryEz(pkthsys);
	sys_DeleteHeap(HEAPID_CONTEST);
}
